/**
  ******************************************************************************
  * @file    GPIO/GPIO_IOToggle/stm32f4xx_it.c 
  * @author  MCD Application Team
  * @version V1.4.0
  * @date    04-August-2014
  * @brief   Main Interrupt Service Routines.
  *          This file provides template for all exceptions handler and 
  *          peripherals interrupt service routine.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2013 STMicroelectronics</center></h2>
  *
  * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
  * You may not use this file except in compliance with the License.
  * You may obtain a copy of the License at:
  *
  *        http://www.st.com/software_license_agreement_liberty_v2
  *
  * Unless required by applicable law or agreed to in writing, software 
  * distributed under the License is distributed on an "AS IS" BASIS, 
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_it.h"

#include "cJSON.h"

#include "led.h"
#include "beep.h"
#include "adc.h"
#include "fan.h"
#include "string.h"

extern char window_num;
char commend_buf[128];
extern char commend_buf2[128];
extern char light,temperature,humidity;//光照,温度,湿度
extern char commend_num,commend_flag;//收到的消息是否已读，0已读，1未读

uint16_t tim6_period_cnt;


/** @addtogroup STM32F4xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup GPIO_IOToggle
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/******************************************************************************/
/*            Cortex-M4 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
  * @brief   This function handles NMI exception.
  * @param  None
  * @retval None
  */
void NMI_Handler(void)
{
}

/**
  * @brief  This function handles Hard Fault exception.
  * @param  None
  * @retval None
  */
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Memory Manage exception.
  * @param  None
  * @retval None
  */
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Bus Fault exception.
  * @param  None
  * @retval None
  */
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles Usage Fault exception.
  * @param  None
  * @retval None
  */
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
  * @brief  This function handles SVCall exception.
  * @param  None
  * @retval None
  */
//void SVC_Handler(void)
//{
//}

/**
  * @brief  This function handles Debug Monitor exception.
  * @param  None
  * @retval None
  */
void DebugMon_Handler(void)
{
}

/**
  * @brief  This function handles PendSVC exception.
  * @param  None
  * @retval None
  */
//void PendSV_Handler(void)
//{
//}

/**
  * @brief  This function handles SysTick Handler.
  * @param  None
  * @retval None
  */
//void SysTick_Handler(void)
//{
//}

/******************************************************************************/
/*                 STM32F4xx Peripherals Interrupt Handlers                   */
/*  Add here the Interrupt Handler for the used peripheral(s) (PPP), for the  */
/*  available peripheral interrupt handler's name please refer to the startup */
/*  file (startup_stm32f40xx.s/startup_stm32f427x.s/startup_stm32f429x.s).    */
/******************************************************************************/

/**
  * @brief  This function handles PPP interrupt request.
  * @param  None
  * @retval None
  */
/*void PPP_IRQHandler(void)
{
}*/

/******************************************************************************
函数名：TIM6_DAC_IRQHandler
功能：定时器6中断处理函数---主要用作判断按键复用功能
输入参数：无
输出参数：无
其他说明：
******************************************************************************/
void TIM6_DAC_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM6, TIM_IT_Update) == SET)
	{
		TIM_ClearITPendingBit(TIM6, TIM_IT_Update);
		tim6_period_cnt++;
	}
}

/*****************************************************************************************
函数名：EXTI4_IRQHandler
功能：外部5-9中断处理函数
输入参数：无
输出参数：无
其他说明：按键1复用功能判断

*****************************************************************************************/

void EXTI4_IRQHandler(void)
{	
	
	static char key1_flag = 0;
	
	EXTI_ClearITPendingBit(EXTI_Line4);//清除中断标志
	if(key1_flag == 0)
	{
		key1_flag = 1;
		TIM_Cmd(TIM6, ENABLE);//基本定时器6开始计时
	}
	else if(key1_flag == 1)
	{
		key1_flag = 0;
		TIM_Cmd(TIM6, DISABLE);//基本定时器6停止计时
		if(tim6_period_cnt <= 2)
		{
			tim6_period_cnt = 0;
		}
		else if(tim6_period_cnt > 2 && tim6_period_cnt <= 150)//低于700ms为短按
		{
			GPIO_ToggleBits(GPIOE, GPIO_Pin_8);
			tim6_period_cnt = 0;
		}
		else if(tim6_period_cnt > 150)//高于1000ms为长按
		{
			switch(window_num)
			{
			case 1:
				window_num = 3;
				break;
			case 2:
				window_num = 1;
				break;
			case 3:
				window_num = 2;
				break;	
			}
			tim6_period_cnt = 0;
		}
	}
	
}

/*****************************************************************************************
函数名：EXTI9_5_IRQHandler
功能：外部5-9中断处理函数
输入参数：无
输出参数：无
其他说明：按键2复用功能判断

*****************************************************************************************/
void EXTI9_5_IRQHandler(void)
{
	static char key2_flag = 0;
	
	if(EXTI_GetITStatus(EXTI_Line5) == SET)//判断哪个外部线产生的中断
	{	
		EXTI_ClearITPendingBit(EXTI_Line5);//清除中断标志
		if(key2_flag == 0)
		{
			key2_flag = 1;
			TIM_Cmd(TIM6, ENABLE);//基本定时器6开始计时
		}
		else if(key2_flag == 1)
		{
			key2_flag = 0;
			TIM_Cmd(TIM6, DISABLE);//基本定时器6停止计时
			if(tim6_period_cnt <= 2)
			{
				tim6_period_cnt = 0;
			}
			else if(tim6_period_cnt > 2 && tim6_period_cnt <= 150)//低于700ms为短按
			{
				GPIO_ToggleBits(GPIOE, GPIO_Pin_9);
				tim6_period_cnt = 0;
			}
			else if(tim6_period_cnt > 150)//高于1000ms为长按
			{
				switch(window_num)
				{
				case 1:
					window_num = 2;
					break;
				case 2:
					window_num = 3;
					break;
				case 3:
					window_num = 1;
					break;	
				}
				tim6_period_cnt = 0;
			}
		}
	}
}


/******************************************************************************
函数名：USART2_IRQHandler
功能：串口2中断处理函数
输入参数：无
输出参数：无
其他说明：pd5->tx,	pd6->rx
******************************************************************************/
void USART2_IRQHandler(void)
{
	if(USART_GetITStatus(USART2, USART_IT_RXNE) == SET)//判断是否接收中断
	{
		USART_ClearITPendingBit(USART2, USART_IT_RXNE);	//清除接收中断标志
		USART_SendData(USART1, USART_ReceiveData(USART2));//将串口二接收到的数据通过串口一发送出去
		commend_buf[commend_num] = USART_ReceiveData(USART2);
		if(commend_buf[0] == '+')
		{
			commend_num++;
		}
		else
		{
			memset(commend_buf,0,sizeof(commend_buf));
			commend_num = 0;
		}
				
	}
	if(USART_GetITStatus(USART2, USART_IT_IDLE) == SET)//判断是否接收总线空闲中断
	{
		char* device;
		char* action;
		int fan_level;
		cJSON* cjson;
		
		USART_ReceiveData(USART2);		//总线空闲中断通过读取数据来清除中断标志
		
		//只获取有效数据，防止AT指令被写入buf缓存区
		if(commend_buf[0] == '+' && commend_buf[1] == 'I')
		{
			
			cjson = cJSON_Parse(commend_buf+10);
			

			//cJSON_GetObjectltem返回的是一个cJSON结构体所以我们可以通过函数返回结构体的方式选择返回类型
			
			device = cJSON_GetObjectItem(cjson,"device")->valuestring;
			action = cJSON_GetObjectItem(cjson,"action")->valuestring;
			
			printf("%s",device);
			printf("%s",action);
			
			if(strcmp(device,"LED1") == 0)
			{
				if(strcmp(action,"on") == 0)
				{
					ledOpen(GPIO_Pin_8);
				}
				if(strcmp(action,"off") == 0)
				{
					ledClose(GPIO_Pin_8);
				}
			}
			else if(strcmp(device,"LED2") == 0)
			{
				if(strcmp(action,"on") == 0)
				{
					ledOpen(GPIO_Pin_9);
				}
				if(strcmp(action,"off") == 0)
				{
					ledClose(GPIO_Pin_9);
				}
			}
			else if(strcmp(device,"buzzer") == 0)
			{
				if(strcmp(action,"on") == 0)
				{
					beepOpen();
				}
				if(strcmp(action,"off") == 0)
				{
					beepClose();
				}
			}
			else if(strcmp(device,"fan") == 0)
			{
				fan_level = cJSON_GetObjectItem(cjson,"fan_level")->valueint;
				if(strcmp(action,"on") == 0)
				{
					if(fan_level == 0)
					{
						TIM_SetCompare2(TIM12, 0);
						fanOpen();
					}
					if(fan_level == 1)
					{
						TIM_SetCompare2(TIM12, 400);
						fanOpen();
					}
					if(fan_level == 2)
					{
						TIM_SetCompare2(TIM12, 700);
						fanOpen();
					}
					if(fan_level == 3)
					{
						TIM_SetCompare2(TIM12, 1000);
						fanOpen();
					}
						
				}
				else if(strcmp(action,"off") == 0)
				{
					TIM_SetCompare2(TIM12, 0);
					fanOpen();
				}
			}
			commend_flag = 1;
			strcpy(commend_buf2,commend_buf);
			cJSON_Delete(cjson);
		}
		memset(commend_buf,0,sizeof(commend_buf));
		commend_num = 0;	
	}
}	


			
//			if(strcmp(commend_buf+7,"openled1") == 0)
//			{
//				ledOpen(GPIO_Pin_8);
//			}
//			else if(strcmp(commend_buf+7,"openled2") == 0)
//			{
//				ledOpen(GPIO_Pin_9);
//			}
//			else if(strcmp(commend_buf+7,"openbeep") == 0)
//			{
//				beepOpen();
//			}
//			else if(strcmp(commend_buf+7,"closeled1") == 0)
//			{
//				ledClose(GPIO_Pin_8);
//			}
//			else if(strcmp(commend_buf+7,"closeled2") == 0)
//			{
//				ledClose(GPIO_Pin_9);
//			}
//			else if(strcmp(commend_buf+7,"closebeep") == 0)
//			{
//				beepClose();
//			}


/******************************************************************************
函数名：TIM2_IRQHandler
功能：定时器2中断处理函数---主要用作传感器定时获取数据
输入参数：无
输出参数：无
其他说明：
******************************************************************************/
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2, TIM_IT_Update) == SET)
	{
		TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
		
		//led3通过光照传感器自动控制
			
		light = 100-100*adcAverageValue()/4096;
		
		if(light <= 50)
		{
			TIM_SetCompare2(TIM1, 1000);
			ledOpen(GPIO_Pin_10);
		}
		else if(light <= 80)
		{
			TIM_SetCompare2(TIM1, 300);
			ledOpen(GPIO_Pin_10);
		}
		else if(light <= 100)
		{
			TIM_SetCompare2(TIM1, 0);
			ledOpen(GPIO_Pin_10);
		}

//		if(temperature > 25)
//		{
//			TIM_SetCompare2(TIM12, 1000);
//			fanOpen();
//		}
//		else if(temperature > 20)
//		{
//			TIM_SetCompare2(TIM12, 500);
//			fanOpen();
//		}
//		else
//		{
//			TIM_SetCompare2(TIM12, 0);
//			fanOpen();
//		}
		
	}
}





/**
  * @}
  */ 

/**
  * @}
  */ 


/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
